import java.util.Scanner;
import java.util.Date;
import java.util.Map;
import java.util.HashMap;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;

public class ATM{
    
    private String DB_NAME = "hw24";
    private String USER_NAME = "root";
    private String PASSWORD = "";
    
    String USER_TABLE = "user";    
    
    User currentUser;           //当前用户引用
    Scanner scan;               //内部Scanner实例
    DBManager dbm;              //DBManager
    
    public ATM()
    throws Exception{
        try{
            this.currentUser = null;
            scan = new Scanner(System.in);
            dbm = new DBManager(DB_NAME, USER_NAME, PASSWORD);
        }catch(Exception e){
            throw e;
        }
    }
    
    public void execute()
    throws Exception{
        try{
            boolean out = false;
            int choose;
            while(!out){
                /*
                    判断是否存在当前用户，如果不存在，则需要创建或登陆
                                        如果存在，则打印用户操作菜单
                */
                if(currentUser == null){
                    do{
                        System.out.println();
                        System.out.println("---- 主菜单 ----");
                        System.out.println("1.创建用户\n"+
                                           "2.登陆\n"+
                                           "3.退出");
                        choose = scan.nextInt();
                    }while(choose > 3 || choose < 1);
                    
                    switch(choose){
                        //调用 创建用户 视图
                        case 1: createUserView(); break;
                        //调用 登陆 视图
                        case 2: loginView(); break;
                        //退出
                        case 3: out = true; break;
                        default: break;
                    }
                }else{
                    /*
                        用户操作菜单，前提需要用户登录
                    */
                    do{
                        System.out.println();        
                        System.out.println("---- 用户操作菜单 ----");            
                        System.out.println("1.存款\n"+
                                           "2.取款\n"+
                                           "3.查看余额\n"+
                                           "4.退出");
                        choose = scan.nextInt();
                    }while(choose > 4 || choose < 1);
                    
                    switch(choose){
                        //调用 存款 视图
                        case 1: depositView(); break;
                        //调用 查看余额 视图
                        case 2: withdrawView(); break;
                        //调用 查看余额 视图
                        case 3: balanceView(); break;
                        //退出
                        case 4: currentUser = null; break;
                        default: break;
                    }
                }
            }
        }catch(Exception e){
            //抛出给调用者
            throw e;
        }
    }
    
    //创建用户 视图
    private void createUserView(){
        System.out.println();
        System.out.println("---- 创建用户 ----");
        
        System.out.print("用户名: ");
        String userName = scan.next();
        
        System.out.print("密码: ");
        String password = scan.next();
        
        try{
            String cardId = createUserController(userName, password);
            System.out.println("请记住您的卡号: " + cardId);
        }catch(Exception e){
            System.out.println(e.getMessage());
        }
    }
    
    //创建用户 控制器
    private String createUserController(String userName, String password)
    throws Exception{
        try{
            String cardId = this.createCardId();
            User tmp = new User(userName, password, cardId);
            dbm.insert(USER_TABLE, tmp.getMap());
            
            return cardId;
        }catch(Exception e){
            throw e;
        }
    }
    
    private String createCardId(){
        Date d = new Date();
        String cardId = "" + (1900 + d.getYear())
                           + d.getMonth()
                           + d.getDate()
                           + d.getHours()
                           + d.getMinutes()
                           + d.getSeconds();
        return cardId;
    }
    
    //登陆 视图
    private void loginView(){
        System.out.println();        
        System.out.println("---- 登陆 ----");
        
        System.out.print("用户名: ");
        String userName = scan.next();
        
        System.out.print("密码: ");
        String password = scan.next();
        
        System.out.print("卡号: ");
        String cardId = scan.next();
        
        try{
            loginController(userName, password, cardId);
            
            System.out.println("\n--> 登陆成功");
        }catch(Exception e){
            System.out.println(e.getMessage());
        }
    }
    
    //登陆 控制器
    private void loginController(String userName, String password, String cardId)
    throws Exception{
        try{
            User loginUser = new User(userName, password, cardId);
            Map<String, Object> userMap = loginUser.getMap();
            userMap.remove("balance");
            // userMap.remove("username");
            // userMap.remove("password");
            ResultSet rs = dbm.select(USER_TABLE, userMap);
            ResultSetMetaData rsmd = rs.getMetaData();
            
            if(rsmd.getColumnCount() == 0){
                currentUser = null;
                throw new Exception("--> 卡号，账户名或密码错误");
            }   
            
            currentUser = loginUser;
            rs.next();
            long bal = Long.parseLong(rs.getString("balance"));
            this.currentUser.setBalance(bal);
        }catch(Exception e){
            currentUser = null;
            throw e;
        }
    }
    
    private ResultSet checkCardId(String cardiId, Map<String, Object> args)
    throws Exception{        
        try{
            ResultSet rs = dbm.select(USER_TABLE, args);
            return rs;
        }catch(Exception e){
            throw e;
        }
    }
    
    private void getUser(String userName, String password, String cardId, ResultSet rs)
    throws Exception{
            
        String userName_db = (String)rs.getObject("username");
        String password_db = (String)rs.getObject("password");
        long balance_db = (long)rs.getObject("balance");
        String cardId_db = (String)rs.getObject("cardid");  
        
        User currentUser_tmp = new User(userName_db, password_db, balance_db, cardId_db);
        User loginUser = new User(userName, password, cardId);
        if(currentUser_tmp.equals(loginUser)){
            this.currentUser = currentUser_tmp;
        }else{
            throw new Exception("--> 用户名或密码错误");
        }        
    }
    
    //存款 视图
    private void depositView(){
        System.out.println();        
        System.out.println("---- 存款 ----");
        
        System.out.print("存款额度: ");
        long acount = scan.nextLong();
        
        try{
            depositController(acount);
            System.out.println("\n--> 存款成功");
        }catch(Exception e){
            System.out.println(e.getMessage());
        }
    }
    
    //存款 控制器
    private void depositController(long acount)
    throws Exception{
        try{
            Map<String, Object> map = currentUser.getMap();
            Map<String, Object> set = new HashMap<String, Object>();
            set.put("balance", ((long)map.get("balance") + acount));
            Map<String, Object> where = new HashMap<String, Object>();
            where.put("cardid", map.get("cardid"));
            
            int row = dbm.update(USER_TABLE, set, where);
            if(row == 0){
                throw new Exception("--> 存款失败");
            }
            currentUser.deposit(acount);
        }catch(Exception e){
            throw e;
        }
    }
    
    //取款 视图
    protected void withdrawView(){
        System.out.println();
        System.out.println("---- 取款 ----");
        
        System.out.print("取款额度: ");
        long acount = scan.nextLong();
        
        try{
            withdrawController(acount);
            System.out.println("\n--> 取款成功");
        }catch(Exception e){
            System.out.println(e.getMessage());
        }
    }
    
    //取款 控制器
    protected void withdrawController(long acount) 
    throws Exception{
        try{
            Map<String, Object> map = currentUser.getMap();
            Map<String, Object> set = new HashMap<String, Object>();
            set.put("balance", ((long)map.get("balance") - acount));
            Map<String, Object> where = new HashMap<String, Object>();
            where.put("cardid", map.get("cardid"));
            
            int row = dbm.update(USER_TABLE, set, where);
            if(row == 0){
                throw new Exception("--> 取款失败");
            }
            currentUser.withdraw(acount);
        }catch(Exception e){
            throw e;
        }
    }
    
    //查看余额 视图
    private void balanceView(){
        long bal = currentUser.getBalance();
        System.out.println("\n--> 您的余额: " + bal);
    }
    
}